package org.fastsyncer.rest.controller;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.fastsyncer.common.constant.CommonConstant;
import org.fastsyncer.common.entity.RestResult;
import org.fastsyncer.common.util.ApplicationUtil;
import org.fastsyncer.common.util.JsonUtil;
import org.fastsyncer.common.util.UUIDUtil;
import org.fastsyncer.core.service.ManagerService;
import org.fastsyncer.core.service.TokenService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 系统集成
 * 
 * @ClassName: RestController
 * @Description: 系统集成授权,远程控制
 * @author AE86
 * @date: 2018年9月19日 上午15:38:01
 */
@Controller
@RequestMapping(value = "/rest")
public class RestController implements ApplicationListener<ContextRefreshedEvent> {

    private static final Logger logger = LoggerFactory.getLogger(RestController.class);

    /**
     * 用户客户端访问凭据
     */
    private static final String TOKEN = "token";

    /**
     * 客户端请求参数
     */
    private static final String PARAMS = "params";

    /**
     * 缓存提供的API
     */
    private static Map<String, Method> cache = new HashMap<>();

    @Autowired
    private TokenService token;

    @Autowired
    private ManagerService manager;

    /**
     * 当spring上下文加载完毕后执行
     */
    @Override
    public void onApplicationEvent(ContextRefreshedEvent e) {
        if (null == e.getApplicationContext().getParent()) {
            // 暴露的API方法
            List<String> list = Arrays.asList("add", "update", "enable", "disable", "enable", "start", "stop", "delete", "getDriver", "getDriverAll");
            // 找到对应的Method放入缓存
            Class<? extends ManagerService> c = manager.getClass();
            Method[] methods = c.getMethods();
            cache = new HashMap<>(list.size());
            String n = null;
            for (Method m : methods) {
                n = m.getName();
                for (String name : list) {
                    if (name.equals(n)) {
                        cache.put(n, m);
                        break;
                    }
                }
            }
            list = null;
        }
    }

    @RequestMapping(value = "/oauth", method = { RequestMethod.POST })
    @ResponseBody
    public RestResult login(HttpServletRequest request, @RequestParam(value = "username") String username, @RequestParam(value = "userpwd") String userpwd) {
        try {
            // 验证口令
            String acc = ApplicationUtil.getKey(CommonConstant.CONFIG_ADMIN_ACCOUNT);
            String pwd = ApplicationUtil.getKey(CommonConstant.CONFIG_ADMIN_PWD);
            if (acc.equals(username) && pwd.equals(userpwd)) {
                String uuid = UUIDUtil.getUUID();
                token.put(uuid, username);
                logger.info("login success!");
                return RestResult.restSuccess(uuid);
            }
        } catch (Exception e) {
            logger.error(e.getLocalizedMessage(), e.getClass());
        }
        return RestResult.restFail("对不起,您输入的帐号或密码错误");
    }

    @RequestMapping(value = "/api/{method}", method = { RequestMethod.POST })
    @ResponseBody
    public RestResult api(HttpServletRequest request, @PathVariable("method") String method) {
        try {
            if (StringUtils.isBlank(method)) {
                throw new IllegalArgumentException("参数无效");
            }

            @SuppressWarnings("unchecked")
            Map<String, String[]> params = request.getParameterMap();
            if (null != params && !params.isEmpty()) {
                // 检查token是否有效
                String[] args = params.get(TOKEN);
                if (null == args || args.length < 1 || null == token.get(args[0])) {
                    return RestResult.restFail("Token无效或已过期", 401);
                }
            }
            // 调用方法
            return RestResult.restSuccess(this.call(method, params));
        } catch (Exception e) {
            String msg = e.getLocalizedMessage();
            if(StringUtils.isBlank(msg)){
                msg = String.valueOf(e.getCause());
            }
            logger.error(msg, e.getClass());
            return RestResult.restFail(msg, 400);
        }
    }

    private Object call(String method, Map<String, String[]> params) throws Exception {
        // 检查是否支持该方法
        Method m = cache.get(method);
        if (null == m) {
            throw new IllegalArgumentException("不支持该方法");
        }

        // 代理调用方法
        Object[] args = params.get(PARAMS);
        Object invoke = m.invoke(manager, args);
        return JsonUtil.objToJson(invoke);
    }

}
